/**
 * WebTree.js
 * @author Ulyan Sobin
 * @description WebTree class
 */

"use strict";

const { WebHandler } = require("./WebHandler");
const { WebNode } = require("./WebNode");
const { WebClient } = require("./WebClient");

class WebTree extends WebNode {
	/**
	 * @private
	 * @type { Object.<string, WebNode> } 
	 */
	subNode;

	/**
	 * Constructor of `WebTree`
	 * @param { Object.<string, (Object.<string, any> | WebHandler)> } tree
	 */
	constructor(tree) {
		super();
		this.subNode = {};
		if (typeof(tree) == "object") {
			for (let key in tree) {
				let value = tree[key];
				if (value instanceof WebNode)
					this.set(key, value);
				else if (typeof(value) == "object")
					this.set(key, new WebTree(value));
			}
		}
	}

	/**
	 * Set node by name
	 * @param { string } name
	 * @param { WebNode } node 
	 */
	set(name, node) {
		this.subNode[name] = node;
	}

	/**
	 * Get node by name
	 * @param { string } name
	 * @returns { WebNode }
	 */
	get(name) {
		return this.subNode[name];
	}

	/**
	 * Route the request from the client
	 * @param {WebClient} client 
	 */
	route(client) {
		let np = client.peekNext();
		if (np == undefined || np == "")
			np = "default";
		let next = this.get(np);
		if (!next) {
			let def = this.get("default");
			if (def instanceof WebHandler)
				def.route(client);
			else
				throw new Error(`No such web path '${np}'`);
		}
		client.routeNext();
		next.route(client);
	}
}

module.exports.WebTree = WebTree;